package com.tungse.study.scheedule;

import com.tungse.study.threadpool.MyThreadPool;
import com.tungse.study.threadpool.ThrowRejectHandle;

import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;

/**
 * 自定义的一个定时任务调度器
 * @author Tungse
 */
public class ScheduleService {

    Trigger trigger = new Trigger();
//    ExecutorService executorService = Executors.newFixedThreadPool(6);
    MyThreadPool executorService = new MyThreadPool(6, 6, 1000, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(10), new ThrowRejectHandle());
    public void execute(Runnable task, long delay) {
        schedule(task, delay, 0);
    }

    public void schedule(Runnable task, long delay, long period) {
        Job job = new Job(task, System.currentTimeMillis() + delay, period);
        trigger.jobQueue.offer(job);
        trigger.wakeUp();
    }

    class Trigger {
        //阻塞有序队列
        PriorityBlockingQueue<Job> jobQueue = new PriorityBlockingQueue<>();
        Thread thread = new Thread(() -> {
            while (true) {
                while (jobQueue.isEmpty()) {
                    //阻塞线程
                    LockSupport.park();
                }
                try {
                    Job latelyJob = jobQueue.peek();
                    if (latelyJob.getStartTime() <= System.currentTimeMillis()) {
                        Job job = jobQueue.poll();
                        executorService.execute(job.getTask());
                        if (job.getPeriod() > 0) {
                            Job nextJob = new Job(job.getTask(), System.currentTimeMillis() + job.getPeriod(), job.getPeriod());
                            trigger.jobQueue.offer(nextJob);
                        }
                    } else {
                        //阻塞线程， 并设置一个阻塞时间
                        LockSupport.parkUntil(latelyJob.getStartTime());
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });

        {
            thread.start();
            System.out.println("触发器启动了~~~~~~~~~~");
        }


        /*
         * 唤醒阻塞的线程
         */
        void wakeUp() {
            LockSupport.unpark(thread);
        }
    }
}
